//
//  GenerateTopic.swift
//  XingCeHelper
//
//  Created by 申铭 on 2022/7/29.
//

import UIKit

enum PracticeType: String {
    case twoDigitSubtraction = "2位 - 2位"
    case twoDigitAddition = "2位 + 2位"
    case threeDigitSubtraction = "3位 - 3位"
    case threeDigitAddition = "3位 + 3位"
    case twoDigitMultiplyOneDigit = "2位 * 1位"
    case twoDigitDivisionOneDigit = "2位 ÷ 1位"
    case exponentiation = "常用年均增长率1" // 求幂
    case base = "常用年均增长率2"
    case fraction2Decimal = "百分数 → 小数"
    case decimal2Fraction = "小数 → 百分数"
    
    
    
    case reciteIdiom = "背成语"
    case reciteSpecification = "背规范词语"
    case reciteIssuesAndMeasure = "背问题对策"
    
    /// 下一项
    func getNext() -> PracticeType {
        switch self {
            case .twoDigitAddition:
                return .twoDigitSubtraction
            case .twoDigitSubtraction:
                return .threeDigitAddition
            case .threeDigitAddition:
                return .threeDigitSubtraction
            case .threeDigitSubtraction:
                return .twoDigitMultiplyOneDigit
            case .twoDigitMultiplyOneDigit:
                return .twoDigitDivisionOneDigit
            case .twoDigitDivisionOneDigit:
                return .fraction2Decimal
            case .fraction2Decimal:
                return .decimal2Fraction
            case .decimal2Fraction:
                return .exponentiation
            case .exponentiation:
                return .base
            case .base:
                return .twoDigitAddition
            
            default:
                return .twoDigitAddition
        }
    }
    
}

class GenerateTopic {
    
    func generateDatas(type: PracticeType) -> [BaseTopic] {
        switch type {
        case .twoDigitSubtraction:
            return twoDigitSubtractionData()
        case .twoDigitAddition:
            return twoDigitAdditionData()
        case .threeDigitAddition:
            return threeDigitAdditionData()
        case .threeDigitSubtraction:
            return threeDigitSubtractionData()
        case .twoDigitMultiplyOneDigit:
            return twoDigitMultiplyOneDigitData()
        case .twoDigitDivisionOneDigit:
            return twoDigitDivisionOneDigitData()
        case .exponentiation:
            return getExponentiationData()
        case .base:
            return getBaseData()
        case .fraction2Decimal:
            return getFraction2DecimalData()
        case .decimal2Fraction:
            return getDecimal2Fraction()
        default:
            return getDecimal2Fraction()
        }
    }
    
    /// 两位数减法
    func twoDigitSubtractionData() -> [CalculationTopic] {
        var topics = [CalculationTopic]()
        for _ in 0...9 {
            topics.append(generateCalcTopic())
        }
        
        return topics
    }
    
    /// 两位数加法
    func twoDigitAdditionData() -> [CalculationTopic] {
        var topics = [CalculationTopic]()
        for _ in 0...9 {
            let num1 = (11...100).random
            let num2 = (11...100).random
            
            let topic = CalculationTopic()
            topic.num1 = num1
            topic.num2 = num2
            topic.symbol = .add
            
            topics.append(topic)
        }
        
        return topics
    }
    
    /// 三位数减法
    func threeDigitSubtractionData() -> [CalculationTopic] {
        var topics = [CalculationTopic]()
        for _ in 0...9 {
            var num1 = (101...999).random
            var num2 = (101...999).random
            
            if num1 < num2 {
                swap(&num1, &num2)
            }
            
            let topic = CalculationTopic()
            topic.num1 = num1
            topic.num2 = num2
            topic.symbol = .sub
            topics.append(topic)
        }
        return topics
    }
    
    /// 三位数加法
    func threeDigitAdditionData() -> [CalculationTopic] {
        var topics = [CalculationTopic]()
        for _ in 0...9 {
            let num1 = (101...999).random
            let num2 = (101...999).random
            
            let topic = CalculationTopic()
            topic.num1 = num1
            topic.num2 = num2
            topic.symbol = .add
            topics.append(topic)
        }
        return topics
    }
    
    /// 两位数 * 一位数
    func twoDigitMultiplyOneDigitData() -> [CalculationTopic] {
        var topics = [CalculationTopic]()
        for _ in 0...9 {
            var num1 = (12...99).random
            if num1 % 10 == 0 {
                num1 = num1 + (2...9).random
            }
            let num2 = (2...9).random
            
            let topic = CalculationTopic()
            topic.num1 = num1
            topic.num2 = num2
            topic.symbol = .multiply
            topics.append(topic)
        }
        return topics
    }
    
    func twoDigitDivisionOneDigitData() -> [CalculationTopic] {
        var topics = [CalculationTopic]()
        for _ in 0...9 {
            let num1 = (2...100).random
            let num2 = (2...9).random
            
            let topic = CalculationTopic()
            topic.num1 = num1
            topic.num2 = num2
            topic.symbol = .division
            topics.append(topic)
        }
        return topics
    }
    
    func getExponentiationData() -> [PowerNumTopic] {
        return getPowerNum().shuffled()
    }
    
    func getFraction2DecimalData() -> [FractionTopic] {
        let arr = getFraction().shuffled()
        return Array(arr.prefix(upTo: 10))
    }
    
    func getBaseData() -> [PowerNum2Topic] {
        var topics = [PowerNum2Topic]()
        
        topics.append(PowerNum2Topic(base: 1.05, exponential: 4))
        topics.append(PowerNum2Topic(base: 1.1, exponential: 4))
        topics.append(PowerNum2Topic(base: 1.15, exponential: 4))
        topics.append(PowerNum2Topic(base: 1.2, exponential: 4))
        topics.append(PowerNum2Topic(base: 1.25, exponential: 4))
        topics.append(PowerNum2Topic(base: 1.3, exponential: 4))
        topics.append(PowerNum2Topic(base: 1.4, exponential: 4))
        
        topics.append(PowerNum2Topic(base: 1.1, exponential: 3))
        topics.append(PowerNum2Topic(base: 1.2, exponential: 3))
        topics.append(PowerNum2Topic(base: 1.3, exponential: 3))
        topics.append(PowerNum2Topic(base: 1.4, exponential: 3))
        
        return topics.shuffled()
    }
    
    func getDecimal2Fraction() -> [DecimalTopic] {
        var topics = [DecimalTopic]()
        
        topics.append(DecimalTopic(value: 0.333, numerator: 1, denominator: 3))
        topics.append(DecimalTopic(value: 0.666, numerator: 2, denominator: 3))
        topics.append(DecimalTopic(value: 0.75, numerator: 3, denominator: 4))
        topics.append(DecimalTopic(value: 0.167, numerator: 1, denominator: 6))
        topics.append(DecimalTopic(value: 0.833, numerator: 5, denominator: 6))
        topics.append(DecimalTopic(value: 0.143, numerator: 1, denominator: 7))
        topics.append(DecimalTopic(value: 0.286, numerator: 2, denominator: 7))
        topics.append(DecimalTopic(value: 0.429, numerator: 3, denominator: 7))
        topics.append(DecimalTopic(value: 0.375, numerator: 3, denominator: 8))
        topics.append(DecimalTopic(value: 0.625, numerator: 5, denominator: 8))
        topics.append(DecimalTopic(value: 0.1111, numerator: 1, denominator: 9))
        
        return topics.shuffled()
    }
    
    private func getFraction() -> [FractionTopic] {
        var topics = [FractionTopic]()
        
        for i in 6...9 {
            topics.append(FractionTopic(numerator: 1, denominator: Float(i)))
        }
        for i in 11...17 {
            topics.append(FractionTopic(numerator: 1, denominator: Float(i)))
        }
        topics.append(FractionTopic(numerator: 2, denominator: 3))
        topics.append(FractionTopic(numerator: 2, denominator: 7))
        topics.append(FractionTopic(numerator: 3, denominator: 7))
        topics.append(FractionTopic(numerator: 3, denominator: 4))
        topics.append(FractionTopic(numerator: 3, denominator: 8))
        topics.append(FractionTopic(numerator: 5, denominator: 6))
        
        return topics
    }
    
    private func getPowerNum() -> [PowerNumTopic] {
        var topics = [PowerNumTopic]()
        
        topics.append(PowerNumTopic(base: 1.05, exponential: 4))
        topics.append(PowerNumTopic(base: 1.1, exponential: 4))
        topics.append(PowerNumTopic(base: 1.15, exponential: 4))
        topics.append(PowerNumTopic(base: 1.2, exponential: 4))
        topics.append(PowerNumTopic(base: 1.25, exponential: 4))
        topics.append(PowerNumTopic(base: 1.3, exponential: 4))
        topics.append(PowerNumTopic(base: 1.4, exponential: 4))
        
        topics.append(PowerNumTopic(base: 1.1, exponential: 3))
        topics.append(PowerNumTopic(base: 1.2, exponential: 3))
        topics.append(PowerNumTopic(base: 1.3, exponential: 3))
        topics.append(PowerNumTopic(base: 1.4, exponential: 3))
        
        return topics
    }
    
    private func generateCalcTopic() -> CalculationTopic {
        var num1 = (11...100).random
        var num2 = (11...100).random
        
        if num1 < num2 {
            swap(&num1, &num2)
        } else if num1 == num2 {
            return generateCalcTopic()
        }
        
        let topic = CalculationTopic()
        topic.num1 = num1
        topic.num2 = num2
        topic.symbol = .sub
        return topic
    }
    
}
